package com.a918.controller;

import com.a918.contract.HelloWorld;
import com.a918.dto.TableResponse;
import com.a918.entity.*;
import com.a918.service.UserService;
import com.a918.util.IPGet;
import com.a918.util.PDFCreate;
import com.github.pagehelper.PageHelper;
import com.github.pagehelper.PageInfo;
import org.apache.shiro.SecurityUtils;
import org.apache.shiro.authc.DisabledAccountException;
import org.apache.shiro.authc.IncorrectCredentialsException;
import org.apache.shiro.authc.UnknownAccountException;
import org.apache.shiro.authc.UsernamePasswordToken;
import org.apache.shiro.subject.Subject;
import org.fisco.bcos.sdk.BcosSDK;
import org.fisco.bcos.sdk.client.Client;
import org.fisco.bcos.sdk.crypto.keypair.CryptoKeyPair;
import org.fisco.bcos.sdk.transaction.model.exception.ContractException;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.*;

import javax.imageio.ImageIO;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;
import java.awt.*;
import java.awt.image.BufferedImage;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.OutputStream;
import java.net.URLEncoder;
import java.util.Date;
import java.util.Map;
import java.util.Random;

@Controller
public class UserController {
    private static final org.slf4j.Logger log = org.slf4j.LoggerFactory.getLogger(UserController.class);
    public final String configFile = com.a918.controller.UserController.class.getClassLoader().getResource("fisco-config.toml").getPath();
    private void initSDK() throws ContractException {
        BcosSDK sdk = BcosSDK.build(configFile);
        Client client = sdk.getClient(Integer.valueOf(1));
        CryptoKeyPair cryptoKeyPair = client.getCryptoSuite().getCryptoKeyPair();
        HelloWorld helloWorld = HelloWorld.deploy(client, cryptoKeyPair);
    }
    private UserService userService;

    @Autowired
    public UserController(UserService userService) {
        this.userService = userService;
    }

    @RequestMapping(value={"/","/index"})
    public String hello(){
        return "index";
    }

    @RequestMapping("/console")
    public String console(HttpServletRequest request,Model model) {
        Integer userid = (Integer) request.getSession().getAttribute("id");
        Integer checkstatus = userService.getUserById(userid).getCheckstatus();
        model.addAttribute("checkstatus",checkstatus);

        //审核未通过取审核意见
        if(checkstatus==-1){
            String shenheyijian = userService.getSHYJByCheckid(userid);
            model.addAttribute("shenheyijian",shenheyijian);

        }
        return "back/console";
    }


    @GetMapping("/login")
    public String login() throws ContractException {
//        log.error("Something else is wrong here---login");
        //如果已经认证通过，直接跳转到首页
//        initSDK();
        if (SecurityUtils.getSubject().isAuthenticated()) {
            return "redirect:/index";
        }
        return "user/login";
    }

    @PostMapping("/login")
    public Object login(String username, String password, String code, Model model, HttpSession session,HttpServletRequest request) {

        String sessionCaptcha  = (String)SecurityUtils.getSubject().getSession().getAttribute("CODE");

        if(!sessionCaptcha.equals(code.toUpperCase())){
            model.addAttribute("error","验证码错误！");
            return "user/login";
        }
        Subject subject = SecurityUtils.getSubject();
        UsernamePasswordToken token = new UsernamePasswordToken(username, password);
        String error = null;
        try {
            //shiro帮我们匹配密码什么的，我们只需要把东西传给它，它会根据我们在UserRealm里认证方法设置的来验证
            subject.login(token);
            User user = (User) subject.getPrincipal();
            session.setAttribute("username", user.getUsername());
            session.setAttribute("id", user.getId());
            session.setAttribute("alg", "0");
            userService.insertlog("登录成功","login",user.getUsername(),IPGet.getIp(request));
            return "redirect:/index";
        } catch (UnknownAccountException e) {
            //账号不存在和下面密码错误一般都合并为一个账号或密码错误，这样可以增加暴力破解难度
            error = "账号不存在！";
        } catch (DisabledAccountException e) {
            error ="账号未启用！";
        } catch (IncorrectCredentialsException e) {
            error ="密码错误！";
        } catch (Throwable e) {
            error ="未知错误！";
        }
        if(null != error){
            model.addAttribute("error",error);
            return "user/login";
        }

        return "redirect:/index";
    }

    //系统日志
    @GetMapping("/log")
    public String log(HttpServletRequest request) {
        userService.insertlog("日志管理","log",(String) request.getSession().getAttribute("username"),IPGet.getIp(request));
        return "user/userlog";
    }


    @PostMapping("/log")
    @ResponseBody
    public Object loglist(int page, int limit,@RequestParam Map<String, String> paramMap){
        PageHelper.startPage(page, limit);
        PageInfo<Userlog> pageInfo  = new PageInfo<Userlog>(userService.getLogList(paramMap));
        return new TableResponse(0,"查询成功", pageInfo.getList(),pageInfo.getTotal());
    }


    //退出
    @RequestMapping("/logout")
    public String logout(HttpServletRequest request) {
        userService.insertlog("登出","logout",(String) request.getSession().getAttribute("username"),IPGet.getIp(request));
        SecurityUtils.getSubject().logout();
        return "user/login";
    }

    //验证用户名是否重复
    @PostMapping("/checkUsername")
    @ResponseBody
    public String checkUsername(HttpServletRequest request){
        String username = request.getParameter("username");
        if (userService.getUserByUsername(username)!=null){
            return "duplicate";
        }
        return "success";
    }

    //后门加用户
    @RequestMapping("/adduser_houmen")
    public String adduser_houmen(HttpServletRequest request){
        String method = request.getMethod();
        if(!"POST".equalsIgnoreCase(method)){
            return "user/adduser_houmen";
        }
        String username = request.getParameter("username");
        String password = request.getParameter("password");

        User user = new User();
        user.setUsername(username);
        user.setPassword(password);
        user.setCheckstatus(0);
        user.setCreattime(new Date());
        userService.insertUser(user);
        return "redirect:login";
    }

    @GetMapping("/modifypwd")
    public String modifypasswd(Model model,HttpServletRequest request) {
        userService.insertlog("修改密码","modifypwd",(String) request.getSession().getAttribute("username"),IPGet.getIp(request));
        model.addAttribute("text","111111");
        return "user/modifypwd";
    }

    @PostMapping("/modifypwd")
    @ResponseBody
    public String modifypasswd_submit(HttpServletRequest request) {
        User user = userService.getUserByUsername((String) request.getSession().getAttribute("username"));
        String oldpasswd = request.getParameter("oldpasswd");
        String newpasswd = request.getParameter("newpasswd");
        if(!userService.validatePasswd(user,oldpasswd)){
            return "oldPasswdError";
        }
        user.setPassword(newpasswd);
        userService.updateUser(user);
        return "success";
    }

    //登录验证码
    @GetMapping("/createCode")
    @ResponseBody
    public void createCode(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        BufferedImage bi = new BufferedImage(90, 40, BufferedImage.TYPE_INT_RGB);
        Graphics g = bi.getGraphics();
        //RGB色彩
        Color c = new Color(242, 248, 255);
        // 框中的背景色
        g.setColor(c);
        // 颜色填充像素
        g.fillRect(0, 0, 90, 40);

        // 定义验证码字符数组
        char[] ch = "ABCDEFGHJKMNPQRSTUVWXYZ23456798".toCharArray();
        Random r = new Random();
        int len = ch.length;
        int index;
        StringBuffer sb = new StringBuffer();
        // 取出四个数字
        for (int i = 0; i < 4; i++) {
            // 循环四次随机取长度定义为索引
            index = r.nextInt(len);
            g.setColor(new Color(r.nextInt(88), r.nextInt(188), r.nextInt(255)));
            Font font = new Font("Times New Roman", Font.ITALIC, 18);
            g.setFont(font);
            g.drawString(ch[index] + "", (i * 18) + 10, 30);
            sb.append(ch[index]);
        }

        //放入Session中
        request.getSession().setAttribute("CODE", sb.toString());
        try {
            ImageIO.write(bi, "JPG", response.getOutputStream());
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

    @GetMapping("/printcheckfile")
    public String printcheckfile(HttpServletRequest request,Model model) {
        User user = userService.getUserByUsername((String) request.getSession().getAttribute("username"));
        model.addAttribute("user",user);
        return "user/printcheckfile";
    }


    @RequestMapping("filedownload")
    @ResponseBody
    public void filedownload(HttpServletResponse response, HttpServletRequest request) throws IOException {
        Integer userid = (Integer) request.getSession().getAttribute("id");
        Integer usertype = userService.getUserById(userid).getUsertype();
        response.reset();
        response.setCharacterEncoding("utf-8");
        response.setContentType("application/pdf");
        OutputStream out = response.getOutputStream();

        if(usertype==1){
            MemBwgWithBLOBs bwg = userService.getBwgWithBLOBsByUserid(userid);
            response.setHeader("content-Disposition", "attachment;filename=" + URLEncoder.encode("registerBwg.pdf", "UTF-8"));
            try {
                ByteArrayOutputStream baos= PDFCreate.bwgPdf(bwg);
                baos.writeTo(out);
                out.flush();
                out.close();
            } catch (IOException e) {
                e.printStackTrace();
            }

        }else if(usertype==2){
            MemPerWithBLOBs per = userService.getPerWithBLOBsByUserid(userid);
            response.setHeader("content-Disposition", "attachment;filename=" + URLEncoder.encode("registerPer.pdf", "UTF-8"));
            try {
                ByteArrayOutputStream baos= PDFCreate.perPdf(per);
                baos.writeTo(out);
                out.flush();
                out.close();
            } catch (IOException e) {
                e.printStackTrace();
            }

        }else if(usertype==3){
            MemOth oth = userService.getOthByUserid(userid);
            response.setHeader("content-Disposition", "attachment;filename=" + URLEncoder.encode("registerOth.pdf", "UTF-8"));
            try {
                ByteArrayOutputStream baos= PDFCreate.othPdf(oth);
                baos.writeTo(out);
                out.flush();
                out.close();
            } catch (IOException e) {
                e.printStackTrace();
            }
        }

    }

}
